use Wx 0.15 qw[:allclasses];
use strict;
package wxFindSolution;

use Wx qw[:everything];
use base qw(Wx::Panel);
use strict;
use Storable;
use SetSolution;
use wxLineGraph;
use Scalar::Util qw(blessed);
use GreedyAlgorithm;



sub new {
	my( $self, $parent, $id, $pos, $size, $style, $name ) = @_;
	    
	$parent = undef              unless defined $parent;
	$id     = -1                 unless defined $id;
	$pos    = wxDefaultPosition  unless defined $pos;
	$size   = wxDefaultSize      unless defined $size;
	$name   = ""                 unless defined $name;

	$style = wxDEFAULT_FRAME_STYLE 
		unless defined $style;

	$self = $self->SUPER::new( $parent, $id, $pos, $size, $style, $name );

	#Create controls
	
	#Two panels for the splitter window
	$self->{panel_A} = Wx::Panel->new($self, -1, wxDefaultPosition, wxDefaultSize);
	$self->{graph} = wxLineGraph->new($self, -1, wxDefaultPosition, wxDefaultSize);

	#The problem complexity controls
	$self->{panel_complexity} = Wx::Panel->new($self->{panel_A}, -1, wxDefaultPosition, wxDefaultSize);
	$self->{box_complexity} = Wx::StaticBox->new($self->{panel_complexity}, -1, 'Problem Details');

	#The algorithm options controls
	$self->{panel_algorithm_options} = Wx::Panel->new($self->{panel_A}, -1, wxDefaultPosition, wxDefaultSize);
	$self->{box_algorithm_options} = Wx::StaticBox->new($self->{panel_algorithm_options}, -1, 'Algorithm options');
	$self->{button_solution} = Wx::Button->new($self->{panel_algorithm_options}, -1, "Find Solution");
	$self->{radio_greedy} = Wx::RadioButton->new($self->{panel_algorithm_options},-1,"Greedy algorithm", wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
	$self->{radio_dp} = Wx::RadioButton->new($self->{panel_algorithm_options},-1,"Dynamic programming", wxDefaultPosition, wxDefaultSize);
	
	#The dp options controls
	$self->{panel_dp_options} = Wx::Panel->new($self->{panel_algorithm_options}, -1, wxDefaultPosition, wxDefaultSize);
	$self->{box_dp_options} = Wx::StaticBox->new($self->{panel_dp_options}, -1, 'Discretisation options');
	$self->{radio_step_n} = Wx::RadioButton->new($self->{panel_dp_options},-1,"Number of budget divisions", wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
	$self->{radio_step_size} = Wx::RadioButton->new($self->{panel_dp_options},-1,"Budget division size", wxDefaultPosition, wxDefaultSize);
	$self->{text_input_dp} = Wx::TextCtrl->new($self->{panel_dp_options}, -1, "");
	
	
	
	#Layout
	$self->{sizer} = Wx::BoxSizer->new(wxHORIZONTAL);
	$self->{sizer_A} = Wx::BoxSizer->new(wxVERTICAL);
	$self->{sizer_complexity} = Wx::StaticBoxSizer->new($self->{box_complexity}, wxVERTICAL);
	$self->{panel_complexity}->SetSizer($self->{sizer_complexity});
	$self->{sizer_algorithm_options} = Wx::StaticBoxSizer->new($self->{box_algorithm_options}, wxVERTICAL);
	$self->{panel_algorithm_options}->SetSizer($self->{sizer_algorithm_options});
	$self->{sizer_dp_options} = Wx::StaticBoxSizer->new($self->{box_dp_options}, wxVERTICAL);
	$self->{panel_dp_options}->SetSizer($self->{sizer_dp_options});

	$self->{sizer_dp_options}->Add($self->{radio_step_n});
	$self->{sizer_dp_options}->Add($self->{radio_step_size});
	$self->{sizer_dp_options}->Add($self->{text_input_dp});
	
	
	$self->{sizer_algorithm_options}->Add($self->{radio_greedy});	
	$self->{sizer_algorithm_options}->Add($self->{radio_dp});	
	$self->{sizer_algorithm_options}->Add($self->{panel_dp_options}, 0, wxALIGN_RIGHT|wxALL, 8);	
	$self->{sizer_algorithm_options}->Add($self->{button_solution}, 0, wxALIGN_RIGHT);	

	

	$self->{sizer_A}->AddSpacer(5);
	$self->{sizer_A}->Add($self->{panel_complexity},0,wxEXPAND|wxALL,3);
	$self->{sizer_A}->AddSpacer(20);
	$self->{sizer_A}->Add($self->{panel_algorithm_options},0,wxEXPAND|wxALL,3);

	$self->{panel_A}->SetSizer($self->{sizer_A});
	$self->{panel_complexity}->SetSizer($self->{sizer_complexity});
	$self->{panel_algorithm_options}->SetSizer($self->{sizer_algorithm_options});

	$self->{sizer}->Add($self->{panel_A}, 0);
	$self->{sizer}->Add($self->{graph}, 1, wxEXPAND);
	$self->SetSizer($self->{sizer});
	$self->Layout();
	Wx::Event::EVT_BUTTON($self, $self->{button_solution}->GetId, \&find_solution);
	Wx::Event::EVT_RADIOBUTTON($self, $self->{radio_greedy}->GetId, \&enable_dp_options);
	Wx::Event::EVT_RADIOBUTTON($self, $self->{radio_dp}->GetId, \&enable_dp_options);
	$self->enable_dp_options();
	return $self;
}


sub enable_dp_options {
	my ($self, $event) = @_;
	my $enabled = $self->{radio_dp}->GetValue();
	
	$self->{radio_step_n}->Enable($enabled); 
	$self->{radio_step_size}->Enable($enabled);
	$self->{text_input_dp}->Enable($enabled);
	 
	
	if (defined $event) { $event->Skip(); }	
}

#Set the state
sub set_state {
	my $self = shift;
	$self->{state} = shift;
}

sub find_solution {
	my $self = shift;
	$self->{state}->{solutions} = GreedyAlgorithm::solve_constant_cost($self->{state}->{tree},
		$self->{state}->{survival});
		
	my %curve = $self->{state}->{solutions}->get_cost_pd();
	my @x = sort(keys %curve);
	my @y; 
	foreach(@x) { push(@y, $curve{$_}); }
	
	$self->{graph}->add_line(\@x,\@y);
	
	$self->GetParent()->GetParent()->send_update_signal();
	
}

sub add_status {
	my ($self, $msg, $good) = @_;
	unless (defined $good) { $good = 1; }
	my $text = Wx::StaticText->new($self->{panel_complexity}, -1, $msg, wxDefaultPosition, wxDefaultSize);
	unless ($good) { $text->SetForegroundColour(wxRED); }
	$self->{sizer_complexity}->Add($text);
}

sub update {
	my $self = shift;
	my $problem_selected;

	#Clear the status sizer
	$self->{sizer_complexity}->Clear(1);

	#Find the problem selected
	if ($self->{state}->{survival} == $self->{state}->{survival_pd}) { $problem_selected = 'PD'; } 
	if ($self->{state}->{survival} == $self->{state}->{survival_nap}) { $problem_selected = 'NAP'; } 
	if ($self->{state}->{survival} == $self->{state}->{survival_gnap}) { $problem_selected = 'gNAP'; }
	my $nspecies = 0;
	if (defined $self->{state}->{species}) { $nspecies = scalar @{$self->{state}->{species}}; }

	my $solvable_with_greedy = 'No';
	if ($problem_selected eq 'PD') {
		$solvable_with_greedy = 'Yes';
	}
	
	$self->add_status("Problem selected: $problem_selected", $problem_selected);
	$self->add_status("Survival relationship complete: Yes");
	$self->add_status("Solvable with greedy algorithm: $solvable_with_greedy");
	$self->add_status("Number of species: $nspecies", $nspecies);
	$self->{sizer_complexity}->Layout();
	
	$solvable_with_greedy = $solvable_with_greedy eq 'Yes';
	
	if ($solvable_with_greedy) {
		$self->{radio_greedy}->Enable();
	} else {
		$self->{radio_greedy}->Disable();
		$self->{radio_dp}->SetValue(1);
	}
	
		$self->enable_dp_options();
}

1;